package com.zhoug.http3;


import com.zhoug.logger3.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import androidx.annotation.NonNull;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * Retrofit 创建工厂
 *
 * @Author HK-LJJ
 * @Date 2019/12/6
 * @Description
 */
public class HttpBuilder {
    private static final String TAG = ">>>RetrofitBuilder";

    /**
     * 超时时间 单位秒
     */
    private int connectTimeOut = 10;
    private int writeTimeOut = 60;
    private int readTimeOut = 60;
    /**
     * 断网重连,{
     * 设置false容易发生错误:HTTP FAILED: java.io.IOException: unexpected end of stream on Connection{112.35.27.244:8016, proxy=DIRECT hostAddress=/112.35.27.244:8016 cipherSuite=none protocol=http/1.1}
     * }
     */
    private boolean retry = true;

    /**
     * 请求重定向
     */
    private boolean followRedirects = true;
    /**
     * 是否开启debug
     */
    private boolean debug = false;

    /**
     * debug模式下的日志级别
     */
    private int debugLevel = HttpLogInterceptor.Level.BODY;

    private final List<Interceptor> interceptors = new ArrayList<>();
    private final List<Interceptor> networkInterceptors = new ArrayList<>();
    private OnBuildListener onBuildListener;

    /**
     * 创建OkHttpClient
     *
     * @return
     */
    private OkHttpClient buildOkHttpClient() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();

        builder.connectTimeout(connectTimeOut, TimeUnit.SECONDS)
                .readTimeout(readTimeOut, TimeUnit.SECONDS)
                .writeTimeout(writeTimeOut, TimeUnit.SECONDS)
                .retryOnConnectionFailure(retry)
                .followRedirects(followRedirects);

        //添加拦截器
        for (Interceptor interceptor : interceptors) {
            if (interceptor != null) {
                builder.addInterceptor(interceptor);
            }
        }
        //添加网络拦截器
        for (Interceptor interceptor : networkInterceptors) {
            if (interceptor != null) {
                builder.addNetworkInterceptor(interceptor);
            }
        }

        //添加日志拦截器
        if (debug) {
            HttpLogInterceptor httpLogging = new HttpLogInterceptor();
            httpLogging.setLevel(debugLevel);
            builder.addInterceptor(httpLogging);
        }
        if (onBuildListener != null) {
            onBuildListener.onOkHttpClientBuilder(builder);
        }
        OkHttpClient okHttpClient = builder.build();
        Logger.d(TAG, "OkHttpClient初始化完成");
        return okHttpClient;

    }

    /**
     * 创建Retrofit
     *
     * @param baseUrl
     * @return
     */
    public Retrofit build(String baseUrl) {
        Retrofit.Builder builder = new Retrofit.Builder()
                .client(buildOkHttpClient())
                .baseUrl(baseUrl)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//这个是用来决定你的返回值是Observable还是Call
                .addConverterFactory(ScalarsConverterFactory.create())//标准类型的转换器 解决String类型多了个引号 要放在GsonConverter之前，否则还是会解析成json
                .addConverterFactory(GsonConverterFactory.create());//json字符串转化为对象Gson
        if (onBuildListener != null) {
            onBuildListener.onRetrofitBuilder(builder);
        }
        Retrofit retrofit = builder.build();
        Logger.d(TAG, "retrofit2初始化完成");
        return retrofit;
    }

    /**
     * 连接超时时间
     * @param connectTimeOut
     * @return
     */
    public HttpBuilder setConnectTimeOut(int connectTimeOut) {
        this.connectTimeOut = connectTimeOut;
        return this;
    }

    /**
     * 写入超时时间
     * @param writeTimeOut
     * @return
     */
    public HttpBuilder setWriteTimeOut(int writeTimeOut) {
        this.writeTimeOut = writeTimeOut;
        return this;
    }

    /**
     * 读取数据超时时间
     * @param readTimeOut
     * @return
     */
    public HttpBuilder setReadTimeOut(int readTimeOut) {
        this.readTimeOut = readTimeOut;
        return this;
    }

    /**
     * 断网重连
     * @param retry
     * @return
     */
    public HttpBuilder setRetry(boolean retry) {
        this.retry = retry;
        return this;
    }

    /**
     * 请求重定向
     * @param followRedirects
     * @return
     */
    public HttpBuilder setFollowRedirects(boolean followRedirects) {
        this.followRedirects = followRedirects;
        return this;
    }

    /**
     * 是否打印日志
     * @param debug
     * @return
     */
    public HttpBuilder setDebug(boolean debug) {
        this.debug = debug;
        return this;
    }

    /**
     * 设置日志级别
     * @param debugLevel {@link HttpLogInterceptor.Level}
     * @return
     */
    public HttpBuilder setDebugLevel(int debugLevel) {
        this.debugLevel = debugLevel;
        return this;
    }

    /**
     * 添加拦截器
     * @param interceptor
     * @return
     */
    public HttpBuilder addInterceptor(Interceptor interceptor) {
        interceptors.add(interceptor);
        return this;
    }

    /**
     * 添加网络拦截器
     * @param interceptor
     * @return
     */
    public HttpBuilder addNetworkInterceptor(Interceptor interceptor) {
        networkInterceptors.add(interceptor);
        return this;
    }

    /**
     * 设置配置
     * @param onBuildListener
     */
    public void setOnBuildListener(OnBuildListener onBuildListener) {
        this.onBuildListener = onBuildListener;
    }

    public interface OnBuildListener {
        /**
         * 其它OkHttpClient.Builder配置 如ssl验证
         *
         * @param builder
         */
        void onOkHttpClientBuilder(@NonNull OkHttpClient.Builder builder);

        /**
         * 其它Retrofit.Builder配置
         *
         * @param builder
         */
        void onRetrofitBuilder(@NonNull Retrofit.Builder builder);
    }

}
